You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

96 lines
2.1 KiB

/**
* PATCH /api/cart/items/:id
*
* Update the quantity of a cart item
*
* Request Body:
* {
* quantity: number (positive integer)
* }
*
* Validation:
* - Cart item must exist
* - Cart item must belong to current user/session
* - Quantity must be >= 1
* - Quantity must not exceed available stock
*
* Response:
* {
* success: true,
* message: string,
* cart: CartSummary
* }
*/
import { z } from 'zod'
import { eq } from 'drizzle-orm'
import { cartItems } from '../../../database/schema'
// Request validation schema
const updateQuantitySchema = z.object({
quantity: z.number().int().min(1, 'Quantity must be at least 1'),
})
// Path params validation
const pathParamsSchema = z.object({
id: z.string().uuid('Invalid cart item ID'),
})
export default defineEventHandler(async (event) => {
// Validate path params
const params = await getValidatedRouterParams(event, pathParamsSchema.parse)
const cartItemId = params.id
// Validate request body
const body = await readBody(event)
const { quantity } = await updateQuantitySchema.parseAsync(body)
// Verify cart item belongs to current user/session
const hasPermission = await verifyCartItemOwnership(event, cartItemId)
if (!hasPermission) {
throw createError({
statusCode: 404,
statusMessage: 'Cart item not found',
})
}
const db = await useDatabase()
// Fetch cart item with product details
const cartItem = await db.query.cartItems.findFirst({
where: eq(cartItems.id, cartItemId),
with: {
product: true,
cart: true,
},
})
if (!cartItem) {
throw createError({
statusCode: 404,
statusMessage: 'Cart item not found',
})
}
// Validate quantity against stock
validateQuantityUpdate(quantity, cartItem.product.stockQuantity)
// Update quantity
await db
.update(cartItems)
.set({ quantity })
.where(eq(cartItems.id, cartItemId))
// Update cart timestamp
await touchCart(cartItem.cart.id)
// Return updated cart
const cartSummary = await getCartWithItems(cartItem.cart.id)
return {
success: true,
message: 'Quantity updated successfully',
cart: cartSummary,
}
})